#ifndef HITSZ_DIP_EX2_FILTER_H
#define HITSZ_DIP_EX2_FILTER_H

#include "conv.h"
#include <cmath>
#include <iostream>
#define HITSZ_DIP_EX2_FILTER_DEBUG 1

namespace ex2{
    cv::Mat generate_gaussian_kernel(float sigma2,int kernel_size)
    {
        //gaussian : a*exp(-r^2/2*sigma2)
        float bias;
        if (kernel_size % 2 ==0)
        { //如果为偶数核,那么中间两个元素应该是-0.5 0.5
            //以4为例，对应x应该是-1.5 -0.5 0.5 1.5
            bias = 0.5;
        }
        else
        { //如果为奇数核，可以认为中间元素为(0,0)
            //以5为例,index -2 -1 0 1 2
            bias = 1;
        }
        int x = kernel_size/2 - kernel_size + bias;
        cv::Mat kernel(kernel_size,kernel_size,CV_32FC1,cv::Scalar(0));
        for (int i=0;i<kernel_size;i++)
        {
            int y = kernel_size/2 - kernel_size + bias;
            for (int j=0;j<kernel_size;j++)
            {
                kernel.at<float>(i,j) = expf(-(pow(x,2)+pow(y,2))/(2*sigma2));
                y += 1;
                //每一个kernel步长为1
            }
            x += 1;
        }

#if HITSZ_DIP_EX2_FILTER_DEBUG 
        std::cout<<"generate gaussian kernel:"<<kernel_size<<" x "<<kernel_size;
        std::cout<<",sigma2:"<<sigma2<<std::endl;
        for(int i=0;i<kernel_size;i++)
        {
            for (int j=0;j<kernel_size;j++)
            {
                std::cout<<kernel.at<float>(i,j)<<"\t";
            }
            std::cout<<std::endl;
        }
#endif 
        return kernel;
    }

    /**
     * @brief 腐蚀
     * @param src，输入图像
     * @param dst，输出图像，类型应该为CV_32FC1
     * @param se ,结构元,类型应该为CV_32FC1,其值应归一化
     * @note 先用SE进行卷积，由于输入应该是二值化结果(即0或255)，如果卷积结果不为255,那么其应该为0
     */ 
    void Erode(cv::Mat& src,cv::Mat& dst,cv::Mat& se)
    {
        dst = conv2d(src,se); //做samepadding
        cv::threshold(dst,dst,254,255,cv::THRESH_BINARY);
    }

    /**
     *@brief 膨胀 
     * @param src,输入图像，应该为单通道二值化图像
     * @param dst，输出图像，为CV_32FC1
     * @param se,结构元
     * @note 先用SE进行卷积，如果卷积结果不为0,那么其对应位置就是255
     */
    void Dilate(cv::Mat& src,cv::Mat& dst,cv::Mat& se)
    {
        dst = conv2d(src,se); //做samepadding
        cv::threshold(dst,dst,1,255,cv::THRESH_BINARY);
    }
}
#endif 